<script lang="ts" setup>
import * as vis from "vis-network"
import { nextTick, onMounted, ref } from "vue"
import * as fabric from "fabric"
const chartRef = ref<HTMLDivElement>()
const contextmenu = ref()
const nodes: vis.Node[] = [
  // 每行加上shape: 'circle' ，则节点显示圆形
  { id: 1, label: "Node 1", shape: "circle", title: "Node1Title", shadow: true, group: "1", x: 300, y: 200 },
  { id: 2, label: "Node 2", shadow: true, group: "2" },
  { id: 3, label: "Node 3", shadow: true, group: "2" },
  { id: 4, label: "Node 4", shadow: true, group: "2" },
  { id: 6, label: "Node 6", shadow: true, group: "2" },
  { id: 7, label: "Node 7", shadow: true, group: "2" },
  { id: 8, label: "Node 8", shadow: true, group: "2" },
  { id: 9, label: "Node 9", shadow: true, group: "2" },
  { id: 5, label: "Node 5", shadow: true, group: "2" }
]
//const nodesRef = ref(nodes)
let network: vis.Network
const downImage = () => {
  const canvas = chartRef.value?.querySelector("canvas")
  canvas?.toBlob((blob) => {
    const a = document.createElement("a")
    document.body.append(a)
    a.download = "network.png"
    a.href = window.URL.createObjectURL(blob!)
    a.click()
  })
}
const addNode = (): void => {
  console.log((network as any).body.data.nodes.get())
  network?.addNodeMode()
}
const addEdge = (): void => {
  network.addEdgeMode()
  const arr: [number, number, number, number] = [0, 0, 0, 0]
  new fabric.Line(arr)
}
const exitMode = (): void => {
  network.disableEditMode()
}
const deleteSelected = (): void => {
  network.deleteSelected()
}
const save = (): void => {
  const nodes = (network as any).body.data.nodes.get() as vis.Node[]
  const edges = (network as any).body.data.edges.get() as vis.Edge[]
  nodes.forEach((t) => {
    const p = network.getPosition(t.id!)
    t.x = p.x
    t.y = p.y
  })
  console.log(nodes, edges)
}
const init = () => {
  const edges: vis.Edge[] = [
    // 每行加上label: '关系名称'，则会在线中间显示节点关系名
    { from: 1, to: 3, label: "测试关系", color: "black" },
    { from: 1, to: 2 },
    { from: 2, to: 4 },
    { from: 2, to: 5 },
    { from: 6, to: 5 },
    { from: 6, to: 7 },
    { from: 8, to: 6 },
    { from: 7, to: 9 }
  ]
  const data: vis.Data = {
    nodes: nodes,
    edges: edges
  }
  const options: vis.Options = {
    autoResize: true,
    width: "1000px",
    height: "800px",
    locale: "en", //语言设置：工具栏显示中文
    //设置语言
    locales: {
      en: {
        edit: "编辑",
        del: "删除",
        back: "返回",
        addNode: "添加节点",
        addEdge: "添加连接",
        editNode: "编辑节点",
        editEdge: "编辑连接",
        addDescription: "点击空白处新增节点",
        edgeDescription: "点击一个节点并拖动至需要连接的节点",
        editEdgeDescription: "Click on the control points and drag them to a node to connect to it.",
        createEdgeError: "创建连接失败",
        deleteClusterError: "删除失败",
        editClusterError: "编辑失败"
      }
    },
    configure: {
      enabled: false,
      showButton: true
    },
    manipulation: {
      enabled: false, //该属性表示可以编辑，出现编辑操作按钮
      addNode: (nodeData: vis.Node, callback: Function) => {
        nodeData.label = "我测试"
        console.log(nodeData)
        callback(nodeData)
      },
      addEdge: true,
      // editNode: undefined,
      editEdge: true,
      deleteNode: true,
      deleteEdge: true
    },
    nodes: {
      shape: "box", //设置节点node样式为矩形
      fixed: false, //节点node固定可移动
      font: {
        color: "red", //字体的颜色
        size: 20 //显示字体大小
      },
      scaling: {
        min: 16,
        max: 32 //缩放效果比例
      },
      borderWidth: 1,
      color: {
        border: "red",
        background: "white" // 若是引用图标，背景颜色
      }
    },
    groups: {
      useDefaultGroups: true,
      ws: {
        // 系统定义的形状 dot等 这些官网都可以找到
        shape: "dot",
        color: {
          background: "red"
        }
      }
    },
    layout: {
      randomSeed: 1 // 配置每次生成的节点位置都一样，参数为数字1、2等
      //以分层方式定位节点
      // hierarchical: {
      //   direction: "UD", //分层排序方向
      //   sortMethod: "directed", //分层排序方法
      //   levelSeparation: 100, //不同级别之间的距离
      //   nodeSpacing: 200 // 节点之间的距离
      // }
    },
    physics: {
      enabled: false,
      // 避免重叠
      hierarchicalRepulsion: {
        avoidOverlap: 1
      }
      // barnesHut: { gravitationalConstant: -30000 },
      // barnesHut: {
      //   gravitationalConstant: -80000,
      //   springConstant: 0.001,
      //   springLength: 200
      // },
      // stabilization: false
      // { iterations: 2500 }
    },
    interaction: {
      hover: true,
      dragNodes: true, //是否能拖动节点
      dragView: true, //是否能拖动画布
      multiselect: true, //按 ctrl 多选
      selectable: true, //是否可以点击选择
      selectConnectedEdges: true, //选择节点后是否显示连接线
      hoverConnectedEdges: true, //鼠标滑动节点后是否显示连接线
      zoomView: true //是否能缩放画布
    },
    edges: {
      color: {
        // 连接线的样式
        color: "#848484",
        highlight: "white",
        hover: "#848484",
        inherit: "from",
        opacity: 1.0
      },
      // font: {
      //   align: 'top', //连接线文字位置
      // },
      shadow: true, // 连接线阴影配置
      smooth: true // 是否连线平滑
      //arrows: {to : true }//是否显示方向箭头 箭头指向to节点
    }
  }
  const network = new vis.Network(chartRef.value!, data, options)
  return network
  // network.on("click", (params) => {
  //   console.log(params)
  // })
  // network.on("oncontext", (e) => {
  //   console.log(e)
  //   // 获取节点 id
  //   var nodeId = network.getNodeAt(e.pointer.DOM)
  //   console.log("单击：", network.getPositions(nodeId))
  //   console.log(nodesRef.value)
  // })
}
const registrayEvent = () => {
  network.on("oncontext", (e) => {
    console.log(e)
  })
}
onMounted(() => {
  network = init()
  nextTick(() => {
    registrayEvent()
  })
})
</script>

<template>
  <div class="app-container">
    <v-contextmenu ref="contextmenu">
      <v-contextmenu-item>菜单</v-contextmenu-item>
    </v-contextmenu>

    <el-tooltip content="以图片方式保存当前拓扑图">
      <el-button type="primary" @click="downImage">下载图片</el-button>
    </el-tooltip>
    <el-tooltip content="点击空白处新增节点">
      <el-button type="primary" @click="addNode">新增节点</el-button>
    </el-tooltip>
    <el-tooltip content="左键长按选中一个节点,拖动鼠标到需要连接的节点上">
      <el-button type="primary" @click="addEdge">新增连接</el-button>
    </el-tooltip>
    <el-tooltip content="删除当前选中的节点和连线">
      <el-button type="danger" @click="deleteSelected">删除节点</el-button>
    </el-tooltip>
    <el-tooltip content="退出编辑模式">
      <el-button type="primary" @click="exitMode">退出编辑</el-button>
    </el-tooltip>
    <el-tooltip content="保存当前拓扑图的信息,下次进入时按现有信息渲染">
      <el-button type="primary" @click="save">保存拓扑</el-button>
    </el-tooltip>
    <div ref="chartRef" id="mynetwork" style="width: 100%; min-height: 750px" v-contextmenu:contextmenu />
  </div>
</template>

<style scoped></style>
